package yogaService

import (
	"duoke/model"
	"duoke/model/yogaModel"
	"duoke/service"
	"duoke/service/common"
	"duoke/tables"
	utils "duoke/utils/common"
	"duoke/utils/orm"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/util/gconv"
)

var CourseOrder = new(courseOrderService)

type courseOrderService struct{}

func (s *courseOrderService) CreateOrder(c *gin.Context, fromId int) (string, error) {
	const (
		TablesCourseOrder = "yoga_course_order"
		TablesCourse      = "yoga_course"
	)
	user, err := service.User.Info(c, "id,openid,ip_addr")
	if err != nil || user.Id == 0 {
		return "", errors.New("用户错误")
	}
	// 查看该用户是否已经支付了
	where := fmt.Sprintf("user_id=%d and from_id=%d and state=1", user.Id, fromId)
	count, err := common.Tales.Info(where, "id").Table(TablesCourseOrder).Count()
	if err != nil || count > 0 {
		return "", errors.New("该用户已经支付了")
	}
	// 查找该班课是否存在
	var yc yogaModel.ReqCourse
	get, err := common.Tales.Info(fmt.Sprintf("id=%d", fromId), "id,price,sub_mch_id,acid,name").
		Table(TablesCourse).Get(&yc)
	if err != nil || !get {
		return "", errors.New("该班课不存在")
	}
	// 查看用户是否有未支付得订单
	var m tables.YogaCourseOrder
	get, err = common.Tales.Info(where, "id").Table(TablesCourseOrder).Get(&m)
	if err != nil {
		return "", errors.New("获取数据错误")
	}
	// 数据库保存
	orderNo := utils.Common.GetOrder()
	m = tables.YogaCourseOrder{
		FromId:        fromId,
		UserId:        user.Id,
		TotalAmount:   float32(yc.Price),
		OrderNo:       orderNo,
		SubMchId:      yc.SubMchId,
		IpAddr:        user.IpAddr,
		Body:          "班课报名",
		Acid:          yc.Acid,
		Openid:        user.Openid,
		State:         2,
		SeparateState: 2,
		ClassName:     yc.Name,
	}
	if !get {
		insert, err := orm.Db.Table(TablesCourseOrder).Insert(&m)
		if err != nil || insert == 0 {
			return "", errors.New("创建订单失败")
		}
	} else {
		insert, err := orm.Db.Where("id", m.Id).Table(TablesCourseOrder).Update(&m)
		if err != nil || insert == 0 {
			return "", errors.New("创建订单失败")
		}
	}
	return orderNo, err
}

func (s *courseOrderService) OrderAmount(c *gin.Context, req *yogaModel.PayOrder) (*yogaModel.ReqCourseOrder, error) {
	// 先判断是否有未支付的订单
	const (
		TablesCourseOrder = "yoga_course_order"
		TablesCourse      = "yoga_course"
		TableOrderSub     = "yoga_order_sub"
		TableConfig       = "yoga_config"
	)
	var sub yogaModel.ReqOrderSub
	where := fmt.Sprintf("order_no='%s' and state=%d", req.OrderNo, 2)
	var order yogaModel.ReqCourseOrder
	get, err := common.Tales.Info(where, "*").Table(TablesCourseOrder).Get(&order)
	if err != nil || !get {
		return nil, errors.New("该订单错误")
	}
	// 查询子表
	where = fmt.Sprintf("order_no='%s'", req.OrderNo)
	get, err = common.Tales.JoinInfo(where, "*").Table(TableOrderSub).Get(&sub)
	if err != nil {
		return nil, errors.New("订单子表错误")
	}
	sub.Yprice = float32(order.TotalAmount)
	// 获取用户信息
	info, err := service.User.Info(c, "openid,score")
	if err != nil && info.Id <= 0 {
		return nil, errors.New("该用户不存在")
	}
	if req.Integral > info.Score {
		return nil, errors.New("积分不足")
	}
	// 获取该预约课程
	where = fmt.Sprintf("id=%d", order.FromId)
	var gc yogaModel.ReqCourse
	get, err = common.Tales.JoinInfo(where, "*").Table(TablesCourse).Get(&gc)
	if err != nil || !get {
		return nil, errors.New("该预约课程错误")
	}
	// 判断积分是否大于可抵扣积分
	if req.Integral > gc.Points {
		return nil, errors.New("积分大于可抵用积分")
	}
	// 获取该商户的配置信息
	where = fmt.Sprintf("sub_mch_id='%s'", gc.SubMchId)
	var yc yogaModel.ReqConfig
	get, err = common.Tales.Info(where, "*").Table(TableConfig).Get(&yc)
	if req.Integral != 0 {
		// 用户抵扣金额
		order.TotalAmount -= float32(req.Integral) / float32(yc.IntegralTransforms)
		sub.IntegralMoney = float32(req.Integral) / float32(yc.IntegralTransforms)
	}
	if req.CouponId != 0 {
		// 优惠券抵扣
		infos, err := service.Coupon.Infos(c, req.CouponId)
		if err != nil && len(infos) <= 0 {
			return nil, errors.New("优惠券错误")
		}
		m := infos[0]
		// type 1 满减需要判断
		if gconv.Int(m["type"]) == 1 {
			if gconv.Float32(m["man"]) > order.TotalAmount {
				return nil, errors.New("未达到该优惠券的使用门槛")
			}
			order.TotalAmount -= gconv.Float32(m["jian"])
			sub.CouponMoney = gconv.Float32(m["jian"])
		} else {
			order.TotalAmount *= 1 - (gconv.Float32(m["zhe"]) / 100)
			sub.CouponMoney = 1 - (gconv.Float32(m["zhe"]) / 100)
		}
	}
	// 插入订单子表
	sub.SubMchId = order.SubMchId
	sub.OrderNo = order.OrderNo
	sub.Integral = req.Integral
	sub.CouponId = req.CouponId
	sub.Price = order.TotalAmount
	sub.Acid = order.Acid
	if sub.Id == 0 {
		insert, err := orm.Db.Table(TableOrderSub).Insert(&sub)
		if err != nil && insert <= 0 {
			return nil, errors.New("创建订单子表失败")
		}
	} else {
		insert, err := orm.Db.Table(TableOrderSub).Where("id=?", sub.Id).Update(&sub)
		if err != nil && insert <= 0 {
			return nil, errors.New("修改订单子表失败")
		}
	}
	return &order, nil
}

func (s *courseOrderService) MyOrder(c *gin.Context, req *model.ReqListV2) (*[]yogaModel.ReqMyCourse, int64, error) {
	// 获取用户数据
	const TablesMyOrder = "yoga_my_course"
	user, err := service.Request.User(c)
	if err != nil && user.Id == 0 {
		return nil, 0, errors.New("获取用户信息错误")
	}
	where := fmt.Sprintf("user_id=%d", user.Id)
	var m []yogaModel.ReqMyCourse
	count, err := common.Tales.Infos(c, &model.ReqListV2{
		PageSize: req.PageSize,
		PageNo:   req.PageNo,
	}, where, "*").Table(TablesMyOrder).Omit("total_amount").FindAndCount(&m)
	return &m, count, err
}
